package css.sword;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;

import java.io.IOException;
import java.net.URL;


@SpringBootApplication
@ComponentScan({"css.sword", "com.fastdfs"})
//@EnableAutoConfiguration(exclude = {
//        org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
//})
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
@EnableScheduling
public class Application {

    @Value("${server.http.port}")
    private int httpPort;

    @Value("${server.https.port}")
    private int httpsPort;

    public static void main(String[] args) {
//        System.setProperty("spring.devtools.restart.enabled", "true");
//        System.setProperty("spring.mvc.dispatch-options-request", "true");
        System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow", "|{}");
        ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
//    String[] na
// mes = applicationContext.getBeanDefinitionNames();
        //1.8 forEach循环
//    Arrays.asList(names).forEach(System.out::println);
        System.out.println("Server start succ");
    }

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");//confidential
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        try {
            tomcat.addAdditionalTomcatConnectors(httpConnector()); // 添加http
            tomcat.addAdditionalTomcatConnectors(createSslConnector());
            System.setProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow", "|{}");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tomcat;
    }

    private Connector createSslConnector() throws IOException {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
        try {
            ClassPathResource keystoreResource = new ClassPathResource("_.szoa.sz.gov.cn.jks");
            URL keystoreUrl = keystoreResource.getURL();
            String keystoreLocation = keystoreUrl.toString();
            // System.out.println(keystoreLocation+"dddddddd");
            connector.setScheme("https");
            connector.setSecure(true);
            connector.setMaxPostSize(20 * 1024 * 1024);
            //演示.联调
//            connector.setPort(443);
            //生产
            connector.setPort(httpsPort);
            protocol.setSSLEnabled(true);
            protocol.setKeystoreFile(keystoreLocation);
            protocol.setKeystorePass("Szoa123456789");
            protocol.setKeystoreType("JKS");
            protocol.setKeyAlias("1");
            protocol.setKeyPass("Szoa123456789");

            return connector;
        } catch (IOException ex) {
            throw new IllegalStateException("can't access keystore: [" + "keystore"
                    + "] or truststore: [" + "keystore" + "]", ex);
        }
    }

    @Bean
    public Connector httpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        //演示.联调
//        connector.setPort(8001);
//        connector.setPort(80);
        //生产
        connector.setPort(httpPort);
        connector.setSecure(true);
        connector.setMaxPostSize(20 * 1024 * 1024);
        //connector.setRedirectPort(443);
        return connector;
    }

    //    @Bean
//    public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
//        StrictHttpFirewall firewall = new StrictHttpFirewall();
//        firewall.setAllowUrlEncodedSlash(true);
//        return firewall;
//    }
//
    @Bean
    public HttpFirewall defaultHttpFirewall() {
        return new DefaultHttpFirewall();
    }

    @Configuration
    public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.authorizeRequests().anyRequest().permitAll().and().headers().frameOptions().disable()
                    .and().csrf().disable();
        }
    }

}